feat: expose S3 presigned download URL on FsNode#419
Conversation
Add download_url and download_url_expiration properties to FsNodeInfo. The oc:downloadURL property was already requested via PROPFIND but never parsed — now it is. Also request nc:download-url-expiration property. When the Nextcloud storage backend is S3 with use_presigned_url enabled, these provide a direct download URL bypassing the Nextcloud proxy. Returns empty string / zero when not available (non-S3 backends). Closes #418
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughPROPFIND parsing now captures Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@nc_py_api/files/__init__.py`:
- Around line 110-111: The constructor assigns self._download_url_expiration
from kwargs without coercion, allowing a string to slip past the intended int
contract; update the code that sets self._download_url_expiration (in the class
__init__ where self._download_url and self._download_url_expiration are
initialized) to coerce the value to an int (e.g.,
int(kwargs.get("download_url_expiration", 0))) and defensively handle
non-numeric inputs (fallback to 0 or raise a clear error) so the attribute is
always an int at runtime.
In `@nc_py_api/files/_files.py`:
- Around line 312-313: The code attempts to parse
prop["nc:download-url-expiration"] into an int unguarded which can raise
ValueError on malformed/non-numeric values; update the block that sets
fs_node_args["download_url_expiration"] to validate or wrap the int(...)
conversion in a try/except ValueError (and TypeError) and on failure assign 0 so
parsing degrades safely; use the existing prop_keys/prop checks and ensure you
reference the same symbols (prop_keys, prop, fs_node_args,
"nc:download-url-expiration") when implementing the guard.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: c699e9bc-52be-4512-9abc-efbf722d7ec6
📒 Files selected for processing (2)
nc_py_api/files/__init__.pync_py_api/files/_files.py
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #419 +/- ##
==========================================
+ Coverage 94.69% 94.73% +0.04%
==========================================
Files 47 48 +1
Lines 5575 5625 +50
==========================================
+ Hits 5279 5329 +50
Misses 296 296
🚀 New features to boost your workflow:
|
Add 7 unit tests covering FsNodeInfo defaults, value pass-through, _parse_record with/without presigned URL data, false values from non-S3 backends, and malformed expiration values. Guard int() conversion of download-url-expiration with contextlib.suppress to handle malformed server responses gracefully.
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@nc_py_api/files/_files.py`:
- Around line 311-312: The code currently treats any non-empty oc:downloadURL
value as truthy, causing the literal string "false" from xmltodict to be stored
in fs_node_args["download_url"]; update the check around prop_keys/prop for
"oc:downloadURL" (in _files.py) to only assign fs_node_args["download_url"] when
prop["oc:downloadURL"] is neither empty nor the literal string "false"
(case-insensitive), otherwise leave/set the default empty string to conform to
the FSNode API.
In `@tests_unit/test_download_url.py`:
- Around line 59-70: The fixture in test_parse_record_with_false_download_url
uses boolean False for "oc:downloadURL" and "nc:download-url-expiration" but
real payloads contain the string "false"; update the values in the test fixture
inside the test_parse_record_with_false_download_url function to use the string
"false" for both "oc:downloadURL" and "nc:download-url-expiration" so the test
mirrors actual XML text parsing and exercises the intended regression path.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 9de4e952-0337-4db5-a0df-33a79cc19d28
📒 Files selected for processing (2)
nc_py_api/files/_files.pytests_unit/test_download_url.py
When S3 storage doesn't support presigned URLs, the server returns <oc:downloadURL>false</oc:downloadURL> which xmltodict parses as the string "false" (truthy in Python). Filter it out explicitly. Also update the test fixture to use string "false" instead of boolean False to match real xmltodict behavior.
Add download_url and download_url_expiration properties to
FsNodeInfo. Theoc:downloadURLproperty was already requested via PROPFIND but never parsed - now it is. Also requestnc:download-url-expirationproperty.When the Nextcloud storage backend is S3 with use_presigned_url enabled, these provide a direct download URL bypassing the Nextcloud proxy. Returns empty string / zero when not available (non-S3 backends).
Closes #418
Summary by CodeRabbit